package io.renren.modules.sys.cas;

import io.renren.config.ShiroConfig;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.entity.SysUserTokenEntity;
import io.renren.modules.sys.service.ShiroService;
import io.renren.modules.sys.service.SysUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cas.CasRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.Set;

/**
 * @author : xingsongtan@qq.com
 * @date : 12:00 2019/7/17
 */
public class MyCasRealm extends CasRealm {
    private static Logger log = LoggerFactory.getLogger(MyCasRealm.class);

    @Resource
    private ShiroService shiroService;
    @Resource
    private SysUserService sysUserService;

    /**
     * 登录时调用 在调用subject.login()时，首先调用此接口
     */
    @Override
    public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        MyCasToken myCasToken=(MyCasToken)token;
        String uiUrl=myCasToken.getUiUrl();
        if(!StringUtils.isEmpty(uiUrl)){
            //casService地址增加uiUrl 否则ticket验证通不过 因为casService地址不一致
            String newCasService= ShiroConfig.casServiceString+"?uiUrl="+uiUrl;
            this.setCasService(newCasService);
        }
        //获取登录用户名
        AuthenticationInfo authenticationInfo = super.doGetAuthenticationInfo(token);
        this.setCasService(ShiroConfig.casServiceString);

        String name = (String) authenticationInfo.getPrincipals().getPrimaryPrincipal();
        String ticket = (String) authenticationInfo.getCredentials();

        // TODO:这里应该从数据库中获取用户信息

        //查询用户信息
        SysUserEntity user = sysUserService.queryByUserName(name);
        if(Objects.isNull(user)){//没有用户信息保存
            user=new SysUserEntity();
            user.setUsername(name);
            user.setStatus(1);
            sysUserService.saveUser(user);
        }
        //账号锁定
        if(user.getStatus() == 0){
            throw new LockedAccountException("账号已被锁定,请联系管理员");
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, ticket, getName());
        return info;
    }

    /**
     * 进行权限验证的时候，调用方法，将用户的权限信息写进SimpleAuthorizationInfo
     */
    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 用户名称
        log.info("进入了权限认证");
        // TODO: 这里应该从数据库获取用户权限
        SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal();
        Long userId = user.getUserId();
        //用户权限列表
        Set<String> permsSet = shiroService.getUserPermissions(userId);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permsSet);
        return info;
    }
}
